package org.anderground.modules.storage;

import java.io.IOException;

/**
 * Simple wrapper around an Object used in I/O operations. Defines methods
 * needed for safe I/O resources management.
 * 
 * @see #openIO()
 * @see #closeIO(Object)
 * 
 * @param <IO>
 *            the Object used in I/O operations
 * 
 * @author Eldar Abusalimov
 */
public interface IOWrapper<IO> {

	/**
	 * Called just before the I/O operations have started.
	 * <p>
	 * Implementation have to prepare an Object that will be used in I/O
	 * operations (for example open a stream or a database).
	 * 
	 * @return the prepared Object that will be used in I/O operations
	 * @throws IOException
	 *             (possibly wrapping another exception) if an I/O error occurs
	 */
	public abstract IO openIO() throws IOException;

	/**
	 * If {@link #shouldCloseIOAfterComplete()} returns true, this method will
	 * be called after the I/O operations have completed.
	 * <p>
	 * Implementation have to close and release any resources associated with
	 * the Object created by {@link #openIO()}.
	 * 
	 * @param io
	 *            the Object previously returned by {@link #openIO()}
	 * @throws IOException
	 *             (possibly wrapping another exception) if an I/O error occurs
	 */
	public abstract void closeIO(IO io) throws IOException;

	/**
	 * Determines whether to call {@link #closeIO(Object)} after the I/O
	 * operations have completed.
	 * 
	 * @return true if {@link #closeIO(Object)} should be called after the I/O
	 *         operations have completed, false if not
	 */
	public abstract boolean shouldCloseIOAfterComplete();

}